home *** CD-ROM | disk | FTP | other *** search
/ World of Amiga / World of Amiga.iso / archive / assembly / lsd-lo.s.lha / FileLoader.Src < prev    next >
Text File  |  1980-01-18  |  11KB  |  569 lines

  1.  
  2. * EXAMPLE OF USE!
  3.  
  4.     
  5.     move.w #$4000,$dff09a    ;disable irqs
  6.  
  7.     jsr INIT_DISK        ;set up
  8.  
  9.     move.l #loadspace,a5    ;address of load
  10.     move.l #filename,a6        ;address of filename
  11.     moveq #0,d7        ;load mode set
  12.  
  13.     jsr LOAD_FILE
  14.  
  15.     tst.w d7            ;check for failure
  16.     beq.s fileok
  17.     move.w #$7fff,d0        ;red screen = error
  18. erlp    move.w #$f00,$dff180
  19.     dbf d0,erlp
  20.  
  21. fileok    jsr MOTOR_OFF
  22.  
  23.     move.w #$c000,$dff09a
  24.     rts
  25.  
  26. loadspace dcb.l $8000,$00
  27.  
  28. filename    dc.b "vegetables/onion",$00
  29.  
  30. *****************************************************************************
  31.  
  32.       *     System Independant AmigaDos File Loader V1.1 - 26/4/94   *
  33.       *--------------------------------------------------------------*
  34.  
  35.                      * By PHIL RUSTON AKA:PHIL!94/LSD *
  36.  
  37. * Call: "INIT_DISK" before you load for the 1st time ever!!!
  38.  
  39. * To LOAD A FILE Set:-
  40.  
  41. * A6 - Address of 0 terminated filename (no path/can include directories).
  42. * A5 - Load address.
  43. * D7 - 0 = Load, 1 = Search and Return file length in A5 only.
  44.  
  45. * Then call: "LOAD_FILE"
  46.  
  47. * Call "MOTOR_OFF" when finished loading for a while!!
  48.  
  49. * A5 returns last byte address of file + 1
  50. * D7 returns 0 is load OK. Or one of the following errors:
  51.  
  52. * 01 = No speed signal from motor   (disk removed while loading?)
  53. * 02 = No DMA transfer time out     (bad disk/ ''            '')
  54. * 03 = Disk removed from drive      (for you to issue requester)
  55. * 04 = Can't find that disk block   (disk corrupt)
  56. * 05 = Wrong track marker ID        ('')
  57. * 06 = Checksum error on disk block ('')
  58. * 07 = Block requested out of range ('')
  59. * 08 = Not a file                   (Its a directory!)
  60. * 09 = File not found               (obvious!)
  61.  
  62. *******************************************************************************
  63.  
  64.     section loadcode,code
  65.  
  66. DRIVE equ 0
  67.  
  68. INIT_DISK    movem.l d7/a1/a2,-(a7)
  69.     bsr motor_off
  70.     move.l #$bfd000,a1
  71.     move.l #variables,a2
  72.     bclr #drive+3,$100(a1)
  73.     bsr initialize_drive
  74.     bsr motor_off
  75.     movem.l (a7)+,d7/a1/a2
  76.     rts
  77.  
  78. LOAD_FILE    movem.l d0-d6/a0-a4/a6,-(a7)
  79.     bsr Find_file
  80.     tst.b error(a2)
  81.     beq.s no_error
  82.     bsr motor_off
  83.     move.w #1000,d7
  84.     bsr cia_wait
  85. no_error    moveq #0,d7
  86.     move.b error(a2),d7
  87.     movem.l (a7)+,d0-d6/a0-a4/a6
  88.     rts
  89.  
  90. MOTOR_OFF    movem.l d7/a1-a2,-(a7)
  91.     move.l #$bfd000,a1
  92.     move.l #variables,a2
  93.     clr.b motor(a2)
  94.     move.b #$ff,$100(a1)
  95.     move.b #$87,$100(a1)
  96.     bsr wait1msec
  97.     move.b #$ff,$100(a1)
  98.     movem.l (a7)+,d7/a1-a2
  99.     rts
  100.  
  101. *********************
  102. * Get Main Root Dir *
  103. *********************
  104.  
  105. Find_file    move.l #$bfd000,a1
  106.     move.l #variables,a2
  107.     move.l a5,load_address(a2)
  108.     clr.b error(a2)
  109.     move.b d7,mode(a2)
  110.  
  111.     move.l #block_buffer,a0    ;get disk's root dir.
  112.     move.w #880,d0
  113.     bsr Get_block
  114.     tst.b error(a2)
  115.     bne file_eror
  116.  
  117. ******************************
  118. * Find File's Root Directory *
  119. ******************************
  120.  
  121. Find_files_root_dir_loop
  122.     
  123.     move.l a6,a4
  124.     moveq #0,d0    
  125.  
  126. dir_loop    move.b (a4),d7        ;find file's root dir
  127.     beq.s root_dir
  128.     cmpi.b #"/",d7        ;and get length of subdir name
  129.     beq.s oblique         ;if required.
  130.     addq.w #1,a4
  131.     addq.w #1,d0
  132.     bra dir_loop
  133.  
  134. oblique    move.w d0,d7        ;d0 = dir name length
  135.     move.w d0,d6        
  136.     subq.w #1,d7
  137.  
  138.     bsr hash_name        ;hash dir name into d0
  139.  
  140.     lsl.w #2,d0
  141.     move.l $18(a0,d0.w),d0    ;header block for this hash
  142.     beq file_not_found
  143.  
  144. get_dir_header
  145.  
  146.     bsr Get_block
  147.     tst.b error(a2)
  148.     bne file_eror
  149.  
  150.     bsr compare_names
  151.     tst.w d7
  152.     beq.s next_in_hash_chain
  153.     addq.w #1,a4
  154.     move.l a4,a6
  155.     bra find_files_root_dir_loop
  156.  
  157. next_in_hash_chain
  158.  
  159.     move.l $1f0(a0),d0
  160.     bne get_dir_header
  161.     bra file_not_found
  162.  
  163. **************************
  164. * Locate The File Itself *
  165. **************************
  166.  
  167. root_dir    move.w d0,d7        ;length of file name
  168.     move.w d0,d6
  169.     subq.w #1,d7
  170.  
  171.     bsr hash_name    
  172.  
  173.     lsl.w #2,d0
  174.     move.l $18(a0,d0.w),d0    ;header block number for this hash
  175.     beq file_not_found
  176.  
  177. get_header
  178.  
  179.     bsr Get_block
  180.     tst.b error(a2)
  181.     bne file_eror
  182.  
  183.     bsr compare_names
  184.     tst.w d7
  185.     bne.s correct_file_header
  186.  
  187.     move.l $1f0(a0),d0        ;any more in hash chain?
  188.     bne get_header
  189.     bra file_not_found
  190.  
  191. correct_file_header
  192.  
  193.     cmpi.l #-3,$1fc(a0)        ;make sure its a file header
  194.     beq.s file_header
  195.     move.b #8,error(a2)        ;not a file header-error 8
  196.     bra file_eror
  197.  
  198. file_header
  199.  
  200.     move.l load_address(a2),a5
  201.     move.l $144(a0),d6        ;length of file.
  202.     tst.b mode(a2)
  203.     beq.s transfer
  204.     move.l d6,a5
  205.     rts
  206. transfer
  207.     subq.l #1,d6    
  208.  
  209. transfer_loop
  210.  
  211.     move.l $10(a0),d0        ;next block location
  212.     beq file_not_found
  213.  
  214.     bsr Get_block
  215.     tst.b error(a2)
  216.     bne file_eror
  217.  
  218. ****************************************
  219. * Download data to file's load address *
  220. ****************************************
  221.  
  222.     lea $18(a0),a3        ;1st data longword in dos_block
  223.     moveq #$79,d7
  224. make_file    subq.l #4,d6
  225.     bmi.s last_bytes
  226.     move.l (a3)+,(a5)+    
  227.     dbf d7,make_file
  228.     bra transfer_loop
  229. last_bytes
  230.     addq.w #4,d6
  231. lb_loop    move.b (a3)+,(a5)+    
  232.     dbf d6,lb_loop
  233.     rts
  234.  
  235. file_not_found
  236.  
  237.     move.b #9,error(a2)        ;file not found-error 8
  238. file_eror    rts
  239.  
  240. *****************************
  241. * File Load Called Routines *
  242. *****************************
  243.  
  244. hash_name    move.l a6,a3
  245. hash_loop    moveq #0,d2        ;hash file name at a6
  246.     move.b (a3)+,d2        ;length-1 in d7.
  247.     cmpi.b #$60,d2
  248.     bls.s capital
  249.     cmpi.b #$7a,d2
  250.     bhi.s capital
  251.     subi.b #$20,d2
  252. capital    mulu #13,d0
  253.     add.l d2,d0
  254.     andi.l #$7ff,d0
  255.     dbf d7,hash_loop
  256.     divu #72,d0
  257.     swap d0            ;d0=hash number
  258.     rts
  259.  
  260. compare_names
  261.  
  262.     moveq #0,d7
  263.     cmp.b $1b0(a0),d6        ;d6=length of name being tested
  264.     bne.s name_fail
  265.     move.w d6,d5
  266.     move.l a6,a3
  267.     lea $1b1(a0),a5
  268.     subq.w #1,d5    
  269. comp_loop    move.b (a3)+,d1        ;Case desensitize filename
  270.     move.b (a5)+,d2        ;compare.
  271.     andi.b #$df,d1
  272.     andi.b #$df,d2
  273.     cmp.b d1,d2
  274.     dbne d5,comp_loop
  275.     tst.w d5
  276.     bpl.s name_fail
  277.     moveq #1,d7
  278. name_fail    rts
  279.  
  280.  
  281. *****************************************************************************
  282.  
  283. ****************************
  284. * Get a block into buffer! *
  285. ****************************
  286.  
  287. * D0 will equal block number required ($0 - $6df)
  288.  
  289. Get_block    movem.l a0-a6/d0-d7,-(a7)
  290.     move.w #$0504,attempts(a2)
  291.     andi.l #$ffff,d0
  292.     cmpi.w #$6df,d0        ;check range
  293.     bls blk_in_range
  294.     move.b #7,error(a2)
  295.     bra no_reload
  296.  
  297. blk_in_range
  298.  
  299.     move.w d0,d1
  300.     divu #11,d1        ;what cylinder is that on?
  301.     tst.b motor(a2)
  302.     beq.s reload
  303.  
  304.     cmp.b trackside(a2),d1    
  305.     beq.s Trksde_in        ;that track is already in.
  306.  
  307. Reload    bsr Fetch_trackside        ;loads track required
  308.     tst.b error(a2)
  309.     bne No_reload
  310.  
  311. Trksde_in    clr.b error(a2)
  312.     move.l #MFMbuffer,a3
  313.     lea $31fe(a3),a0
  314. find_sync    move.w #$4489,d7
  315. fs_loop    cmp.w (a3)+,d7
  316.     beq found_sync
  317.     cmp.l a0,a3
  318.     bls.s fs_loop
  319.     move.b #4,error(a2)        ;couldnt find that sector-error 4
  320.     bra MFM_error
  321.  
  322. found_sync    
  323.  
  324.     cmp.w (a3),d7
  325.     beq.s syncstart
  326.     subq.w #2,a3
  327.  
  328. syncstart    lea $2a(a3),a4        ;Check header checksum.
  329.     bsr decode_lw        
  330.     move.l $2(a3),d3
  331.     move.l $6(a3),d4
  332.     andi.l #$55555555,d3
  333.     andi.l #$55555555,d4
  334.     eor.l d4,d3
  335.     cmp.l d3,d5
  336.     bne Not_sector
  337.  
  338.     lea $2(a3),a4        ;Track mark = Head position?
  339.     bsr decode_lw
  340.     move.l d5,d4        
  341.     swap d4
  342.     cmp.b trackside(a2),d4
  343.     beq Track_mark_ok
  344.     move.b #5,error(a2)        ;wrong track mark - error 5
  345.     bra MFM_error
  346.  
  347. Track_mark_ok
  348.  
  349.     lsr.w #8,d5        ;Is this the sector required?
  350.     move.l d1,d7
  351.     swap d7
  352.     cmp.b d5,d7
  353.     beq.s Found_block
  354.     
  355. Not_sector
  356.  
  357.     add.w #$430,a3          ;loop until find correct sector
  358.     bra find_sync
  359.  
  360. Found_Block
  361.  
  362.     moveq #0,d2        ;Put converted mfm at dest addr.
  363.     move.l #$55555555,d7
  364.     move.l #block_buffer,a6
  365.     lea $3a(a3),a4        
  366.     lea $23a(a3),a5
  367.     moveq #$7f,d3
  368.     
  369. next_lw    move.l (a4)+,d6
  370.     move.l (a5)+,d5
  371.     and.l d7,d6
  372.     and.l d7,d5
  373.     eor.l d6,d2        ;update checksum
  374.     eor.l d5,d2
  375.     add.l d6,d6
  376.     or.l d5,d6
  377.     move.l d6,(a6)+
  378.     dbf d3,next_lw
  379.  
  380.     sub.w #$208,a4
  381.     bsr decode_lw
  382.     cmp.l d5,d2
  383.     beq.s no_reload
  384.     move.b #6,error(a2)        ;checksum error - error 6
  385.     
  386. MFM_error    subq.b #1,attempts(a2)
  387.     bne Reload
  388.     bsr initialize_drive
  389.     move.b #5,attempts(a2)
  390.     subq.b #1,attempts+1(a2)
  391.     bne Reload
  392.     
  393. No_reload    movem.l (a7)+,a0-a6/d0-d7
  394.     rts
  395.  
  396. *****************************************************************************
  397.  
  398. *********************
  399. * MFM Track loader! *
  400. *********************
  401.  
  402. * D1 will equal trackside 0 - 159
  403.  
  404. Fetch_trackside
  405.     
  406.     movem.l a0/d0-d3,-(a7)    
  407.     move.l #$dff000,a0
  408.     clr.b error(a2)        
  409.  
  410.     tst.b motor(a2)
  411.     bne.s motor_on
  412.     move.b #$ff,$100(a1)
  413.     bclr #drive+3,$100(a1)
  414.     bsr wait1msec
  415.     btst #2,$1001(a1)
  416.     bne.s start_mot
  417.     btst #1,trackside(a2)
  418.     beq.s inchk
  419.     bsr stepout
  420.     bra.s stepchk
  421. inchk    bsr stepin
  422. stepchk    btst #2,$1001(a1)
  423.     beq.s no_disk
  424.     bsr initialize_drive
  425.     
  426. start_mot    move.b #$7f,$100(a1)    ;drive selected / motor on.
  427.     bclr #drive+3,$100(a1)
  428.     move.b #1,motor(a2)
  429.     move.w #200,d2        ;wait for correct motor speed.
  430. wdskrdy    moveq #10,d7
  431.     bsr cia_wait        
  432.     btst #5,$1001(a1)        
  433.     dbeq d2,wdskrdy
  434.     tst.w d2
  435.     bpl motor_on
  436.     move.b #1,error(a2)        ;no speed signal - error 1
  437.     bra trackload_end
  438.  
  439. motor_on    btst #2,$1001(a1)        ;disk removed?        
  440.     bne.s disk_in
  441. no_disk    move.b #3,error(a2)
  442.     bra trackload_end
  443.  
  444. disk_in    move.w d1,d3
  445.     lsr.b #1,d3        ;select disk side to load from.
  446.     bcc.s head1
  447.     bclr #2,$100(a1)
  448.     bra checkhead
  449. head1    bset #2,$100(a1)
  450.  
  451. checkhead    move.b trackside(a2),d2    ;ensure head is over correct
  452.     lsr.b #1,d2        ;track
  453.     cmp.b d2,d3
  454.     beq.s headok
  455.     bls.s seekout
  456.     bsr stepin
  457.     bra.s checkhead 
  458. seekout    bsr stepout    
  459.     bra.s checkhead
  460.  
  461. headok    move.b d1,trackside(a2)
  462.     move.w #$2,$9c(a0)        ;clear disk block irq flag
  463.     moveq #18,d7        ;settle wait.
  464.     bsr cia_wait
  465.  
  466.     move.l #mfmbuffer,$20(a0)
  467.     move.w #$4000,$24(a0)    
  468.     move.w #$8010,$96(a0)    ;enable dma
  469.     move.w #$6800,$9e(a0)    
  470.     move.w #$9500,$9e(a0)
  471.     move.w #$4489,$7e(a0)    ;sync
  472.     move.w #$9900,$24(a0)    
  473.     move.w #$9900,$24(a0)    
  474.  
  475.     move.w #200,d2
  476. waitdirq    moveq #10,d7
  477.     bsr cia_wait        
  478.     btst #1,$1f(a0)        
  479.     dbne d2,waitdirq
  480.     tst.w d2
  481.     bpl.s read_ok
  482.     move.b #2,error(a2)        ;No DMA finish-Time Out-error 2
  483.  
  484. read_ok    move.w #$4000,$24(a0)    
  485.     move.w #$10,$96(a0)        ;disable dma
  486.  
  487. Trackload_end
  488.  
  489.     movem.l (a7)+,a0/d0-d3
  490.     rts
  491.  
  492. *******************************************************************************
  493.  
  494. decode_lw    move.l #$55555555,d7    ;decode two consec mfm longwords
  495.     move.l (a4),d5        ;into d5
  496.     move.l $4(a4),d4    
  497.     and.l d7,d5    
  498.     and.l d7,d4
  499.     add.l d5,d5
  500.     or.l d4,d5        
  501.     rts
  502.  
  503. stepout    subq.b #2,trackside(a2)
  504.     bset #1,$100(a1)
  505.     bra.s step
  506.  
  507. stepin    addq.b #2,trackside(a2)
  508.     bclr #1,$100(a1)
  509. step    bsr.s shortwait
  510.     bclr #0,$100(a1)
  511.     bsr.s shortwait
  512.     bset #0,$100(a1)
  513.     moveq #4,d7
  514.     bsr cia_wait
  515.     rts
  516. shortwait
  517.     nop
  518.     nop
  519.     nop
  520.     nop
  521.     rts
  522.  
  523. initialize_drive
  524.  
  525.     btst #$4,$1001(a1)        
  526.     beq.s gottrack0
  527.     bsr.s stepout
  528.     bra.s initialize_drive
  529.  
  530. gottrack0    clr.b trackside(a2)    
  531.     move.w #20,d7
  532.     bsr cia_wait
  533.     rts
  534.  
  535. wait1msec    moveq #1,d7
  536.  
  537. cia_wait    move.b #$08,$f00(a1)    ;set one shot / stop timer.
  538.     move.b #$cc,$600(a1)    ;set timer lo
  539.     move.b #$02,$700(a1)    ;set timer hi (starts counter)
  540. ciawlp2    btst #0,$f00(a1)        ;wait for ciab timer b to timeout
  541.     bne.s ciawlp2
  542.     subq.w #1,d7
  543.     bne.s cia_wait        ;d1 = milliseconds to wait.
  544.     rts
  545.  
  546. *******************************************************************************
  547.  
  548. trackside    equ $0
  549. error           equ $1
  550. motor        equ $2
  551. mode         equ $3
  552. attempts     equ $4
  553. load_address equ $6
  554.  
  555. variables    dcb.w $5,$0000
  556.  
  557. block_buffer    
  558.  
  559.     dcb.w $100,$0000
  560.  
  561.  
  562.     section chipstuff,data_c
  563.  
  564.  
  565. mfmbuffer    dcb.w $1910,$0000
  566.  
  567. *******************************************************************************
  568.  
  569.